/* -*-c++-*- */
/* osgGIS - GIS Library for OpenSceneGraph
 * Copyright 2007-2008 Glenn Waldron and Pelican Ventures, Inc.
 * http://osggis.org
 *
 * osgGIS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */

#ifndef _OSGGIS_MAKE_NODE_FILTER_H_
#define _OSGGIS_MAKE_NODE_FILTER_H_ 1

#include <osgGIS/Common>
#include <osgGIS/NodeFilter>
#include <osg/StateSet>

namespace osgGIS
{
    /**
     * Assembles Fragment instances into osg::Node instances.
     *
     * This is usually the final Filter in a FilterGraph. It takes as input one or
     * more Fragment objects and combines them under Geode and Group objects, optimizing
     * as appropriate.
     *
     * It can also apply finishing touches like mapping an overlay texture, enabling cluster
     * culling, or adjusting the overall GL state attributes line point size and line width.
     */
    class OSGGIS_EXPORT BuildNodesFilter : public NodeFilter
    {
        OSGGIS_META_FILTER( BuildNodesFilter );

    public:
        /**
         * Constructs a BuildNodes filter with default settings.
         */
        BuildNodesFilter();

        /**
         * Copy constructor
         */
        BuildNodesFilter( const BuildNodesFilter& rhs );

        virtual ~BuildNodesFilter();
        
    public:   // properties   

        /**
         * Sets whether to disable GL lighting on the resulting node graphs.
         *
         * @param value
         *      True to disable lighting, false to leave it enabled.
         */
        void setDisableLighting( bool value );
        
        /** 
         * Gets whether to disable GL lighting on the resulting node graphs.
         *
         * @return
         *      True if lighting is disabled, false if not.
         */
        bool getDisableLighting() const;  
        
        /**
         * Sets whether to enable backface culling on the resulting node.
         *
         * @param value
         *      True to set backface culling; false to do nothing
         */
        void setCullBackfaces( bool value );
        
        /**
         * Gets whether to enable backfase culling on the resulting node.
         *
         * @return
         *      True for backface culling; false otherwise
         */
        bool getCullBackfaces() const;
        
        /**
         * Sets whether to apply cluster culling to the resulting node. 
         * Cluster culling is a fast way to cull the entire node based on
         * a single normal vector. (This only applies to localized, geocentric
         * datasets.)
         *
         * @param value
         *      True to enable cluster culling for localized, geocentric data;
         *      False to disable it.
         */
        void setApplyClusterCulling( bool value );
        
        /**
         * Gets whether to apply cluster culling to the resulting node.
         *
         * @return
         *      True if cluster culling will be installed
         */
        bool getApplyClusterCulling() const;  
        
        /**
         * Sets whether to run the OSG optimizer on the resulting node.
         *
         * @param value
         *      True to enable node optimization
         */
        void setOptimize( bool value );
        
        /**
         * Gets whether to run the OSG optimizer on the resulting node.
         *
         * @return True if resulting nodes will get optimized
         */
        bool getOptimize() const;      
        
        /** 
         * Sets the line width to set on the resulting node.
         *
         * @param value
         *      The line width to use, or 0.0f to use the default
         */
        void setLineWidth( float value );

        /**
         * Gets the line width the set on the resulting node.
         *
         * @return The line width, or 0.0f to use the default
         */
        float getLineWidth() const;

        /** 
         * Sets the point size to apply to the resulting node graph.
         *
         * @param value
         *      The point size, or 0.0 to use the default
         */
        void setPointSize( float value );

        /**
         * Gets the point size to apply to the resulting node graph.
         *
         * @return The point size, or 0.0 to use the default
         */
        float getPointSize() const;

        /**
         * Sets a script that evaluates to the name of a RasterResource to use to
         * generate a texture that will by applied to the resulting scene graph. This is
         * useful for generating overlay textures, for example.
         *
         * @param Script
         *      Script that generates a RasterResource name
         */
        void setRasterOverlayScript( Script* script );
        
        /**
         * Gets a script that evalutes to the name of a RasterResource to use as a
         * default scene graph texture.
         *
         * @return
         *      Script that generates a RasterResource name
         */
        Script* getRasterOverlayScript() const;
        
        /**
         * Sets the maximum allowable dimension (width or height) for an overlay texture.
         * The default is 1024.
         *
         * @param size
         *      Maximum texture size (in either dimension)
         */
        void setRasterOverlayMaxSize( int size );
        
        /**
         * Gets the maximum allowable dimension (width or height) for an overlay texture.
         *
         * @return
         *      Maximum texture size (in either dimension)
         */
        int getRasterOverlayMaxSize() const;
        
        /**
         * Sets whether to embed the feature attributes into the scene graph as a
         * osgSim::ShapeAttributeList userdata structure. Default = false.
         *
         * @param value
         *      True to embed the attr name/value pairs; false if not.
         */
        void setEmbedAttributes( bool value );

        /**
         * Gets whether to embed the feature attributes into the scene graph as a
         * osgSim::ShapeAttributeList userdata structure. Default = false.
         *
         * @return True to embed the attr name/value pairs; false if not.
         */
        bool getEmbedAttributes() const;

        /**
         * Sets whether to enable alpha blending on the node's stateset.
         *
         * @param value
         *      True to enable alpha blending (transparency)
         */
        void setAlphaBlending( bool value );

        /**
         * Gets whether to enable alpha blending on the node's stateset.
         *
         * @return True to enable transparency; false otherwise.
         */
        bool getAlphaBlending() const;

    public: // Filter overrides    
        virtual void setProperty( const Property& );
        virtual Properties getProperties() const;
        
    protected: // NodeFilter overrides
        virtual AttributedNodeList process( FragmentList& input, FilterEnv* env );
        virtual AttributedNodeList process( AttributedNodeList& input, FilterEnv* env );

    private:
        float line_width;
        float point_size;
        bool  draw_cluster_culling_normals;
        osg::ref_ptr<Script> raster_overlay_script;
        int raster_overlay_max_size;
        bool cull_backfaces;
        bool apply_cluster_culling;
        bool optimize;
        bool disable_lighting;
        bool embed_attrs;
        bool alpha_blending;

        void init();
    };
}


#endif // _OSGGIS_MAKE_NODE_FILTER_H_
